using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace AdHocReports
{
    public partial class step6 : BasePage
    {
        private const int iColWidth = 25;

        protected void Page_Load(object sender, EventArgs e)
        {
            MasterPage.NextEnabled = true;
            MasterPage.BackEnabled = true;
            MasterPage.CancelEnabled = true;
            MasterPage.NextClicked += new EventHandler(mp_NextClicked);
            MasterPage.BackClicked += new EventHandler(mp_BackClicked);
            MasterPage.CancelClicked += new EventHandler(mp_CancelClicked);
            MasterPage.ContentTitle = "Create a Report: Filters";

            if (!IsPostBack && !IsCallback)
            {
                // Loop through the columns
                for (int i = 0; i < ReportDefinition.DataTypes.Count; i++)
                {
                    // Check the data type
                    switch (ReportDefinition.DataTypes[i].Type)
                    {
                        // Numeric data type
                        case "System.Decimal":
                        case "System.Double":
                        case "System.Int16":
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Single":
                        case "System.UInt16":
                        case "System.UInt32":
                        case "System.UInt64":
                            // Create a list item for numeric filters
                            System.Web.UI.WebControls.ListItem liNumeric = new System.Web.UI.WebControls.ListItem(ReportDefinition.DataTypes[i].Name, ReportDefinition.DataTypes[i].Name);
                            // Add the item to the numeric filter list
                            lstNumeric.Items.Add(liNumeric);
                            // Break the switch
                            break;
                        // Date/Time data type
                        case "System.DateTime":
                            // Create a list item for date/time filters
                            System.Web.UI.WebControls.ListItem liDateTime = new System.Web.UI.WebControls.ListItem(ReportDefinition.DataTypes[i].Name, ReportDefinition.DataTypes[i].Name);
                            // Add the item to the date/time filter list
                            lstDateTime.Items.Add(liDateTime);
                            // Break the switch
                            break;
                        // String data type
                        case "System.Char":
                        case "System.String":
                            // Create a list item for string filters
                            System.Web.UI.WebControls.ListItem liString = new System.Web.UI.WebControls.ListItem(ReportDefinition.DataTypes[i].Name, ReportDefinition.DataTypes[i].Name);
                            // Add the item to the string filter list
                            lstString.Items.Add(liString);
                            // Break the switch
                            break;
                        // Boolean data type
                        case "System.Boolean":
                            // Create a list item for boolean filters
                            System.Web.UI.WebControls.ListItem liBoolean = new System.Web.UI.WebControls.ListItem(ReportDefinition.DataTypes[i].Name, ReportDefinition.DataTypes[i].Name);
                            // Add the item to the boolean filter list
                            lstBoolean.Items.Add(liBoolean);
                            // Break the switch
                            break;
                    }
                }

                // Create a connection object
                using (System.Data.OleDb.OleDbConnection oleConn = new System.Data.OleDb.OleDbConnection(ReportDefinition.ConnectionString))
                {
                    // Get the row count
                    using (System.Data.OleDb.OleDbCommand oleComm = new System.Data.OleDb.OleDbCommand("SELECT COUNT(*) FROM \"" + ReportDefinition.View + "\"", oleConn))
                    {
                        oleComm.Connection.Open();
                        lblQueryRowCount.Text = oleComm.ExecuteScalar().ToString();
                        oleComm.Connection.Close();
                    }
                }

                // Show the numeric filters, hide the others
                trNumeric.Visible = true;
                trDateTime.Visible = false;
                trString.Visible = false;
                trBoolean.Visible = false;
            }
        }

        void mp_CancelClicked(object sender, EventArgs e)
        {
            Response.Redirect("~/");
        }

        void mp_BackClicked(object sender, EventArgs e)
        {
            if (ReportDefinition.GroupColumns.Count > 0)
            {
                Response.Redirect("step5.aspx");
            }
            else
            {
                Response.Redirect("step4.aspx");
            }
        }

        void mp_NextClicked(object sender, EventArgs e)
        {
            // Go to the next step
            Response.Redirect("showReport.aspx");
        }

        protected void cboFilters_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Check the filter selected
            switch (cboFilters.SelectedIndex)
            {
                case 0:
                    // Make numeric filter visible
                    trNumeric.Visible = true;
                    // Hide all other filters
                    trDateTime.Visible = false;
                    trString.Visible = false;
                    trBoolean.Visible = false;
                    break;
                case 1:
                    // Make date/time filter visible
                    trDateTime.Visible = true;
                    // Hide all other filters
                    trNumeric.Visible = false;
                    trString.Visible = false;
                    trBoolean.Visible = false;
                    break;
                case 2:
                    // Make string filter visible
                    trString.Visible = true;
                    // Hide all other filters
                    trNumeric.Visible = false;
                    trDateTime.Visible = false;
                    trBoolean.Visible = false;
                    break;
                case 3:
                    // Make boolean filter visible
                    trBoolean.Visible = true;
                    // Hide all other filters
                    trNumeric.Visible = false;
                    trDateTime.Visible = false;
                    trString.Visible = false;
                    break;
            }
        }

        protected void cboNumericOps_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Check the selected index
            switch (cboNumericOps.SelectedIndex)
            {
                case 0:
                    // Disable all
                    txtNumericOps.Enabled = false;
                    cmdAddNumericRange.Enabled = false;
                    break;
                case 3:
                case 4:
                    // Enable basic with range
                    txtNumericOps.Enabled = true;
                    cmdAddNumericRange.Enabled = true;
                    break;
                case 1:
                case 2:
                case 5:
                case 6:
                case 7:
                case 8:
                    // Enable basic only
                    txtNumericOps.Enabled = true;
                    cmdAddNumericRange.Enabled = false;
                    break;
            }
        }

        protected void cmdAddNumericRange_Click(object sender, EventArgs e)
        {
            int number;

            // If the value is numeric
            if (int.TryParse(txtNumericOps.Text, out number) == true)
            {
                // Create a list item for the value
                System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem(txtNumericOps.Text, txtNumericOps.Text);
                // Add the item
                lstNumericOps.Items.Add(li);
                // Reset the value
                txtNumericOps.Text = "";
            }
        }

        protected void cmdMoveRightNumeric_Click(object sender, EventArgs e)
        {
            // Default to "not okay"
            bool bOK = false;
            // Text and Value for the numeric filter item
            string sText = "";
            string sValue = "";

            // Check the operation being performed
            switch (cboNumericOps.SelectedIndex)
            {
                case 1:
                case 2:
                case 5:
                case 6:
                case 7:
                case 8:
                    int number;

                    // Check if the input is numeric
                    if (int.TryParse(txtNumericOps.Text, out number) == true)
                    {
                        // "okay"
                        bOK = true;
                        // Build the clause
                        sValue = "(" + lstNumeric.SelectedItem.Value + " " + cboNumericOps.SelectedItem.Value + " " + txtNumericOps.Text + ")";
                    }
                    break;
                case 3:
                case 4:
                    // "okay"
                    bOK = true;
                    // Loop through the range
                    for (int i = 0; i < lstNumericOps.Items.Count; i++)
                    {
                        // Append the item values
                        sValue += lstNumericOps.Items[i].Text + ", ";
                    }
                    // Chop off trailing comma
                    sValue = sValue.Substring(0, sValue.Length - 2);
                    // Build the full value
                    sValue = "(" + lstNumeric.SelectedItem.Value + " " + cboNumericOps.SelectedItem.Value + " (" + sValue + "))";
                    break;
            }
            // If the value exceeds the defined column width
            if (sValue.Length > iColWidth)
            {
                // Truncate the display, append ellipsis
                sText = sValue.Substring(0, iColWidth) + "...";
            }
            else
            {
                // Otherwise, show the full value
                sText = sValue;
            }

            // If everything is "okay"
            if (bOK == true)
            {
                // Create the list item for the filter
                System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem(sText, sValue);
                // Add the item
                lstNumericFilters.Items.Add(li);

                ReportDefinition.NumericFilters.Add(sValue);
            }

            // Clear the input controls
            txtNumericOps.Text = "";
            lstNumericOps.Items.Clear();
        }

        protected void cmdMoveLeftNumeric_Click(object sender, EventArgs e)
        {
            ReportDefinition.NumericFilters.Remove(lstNumericFilters.SelectedValue);

            // Remove the filter item
            lstNumericFilters.Items.Remove(lstNumericFilters.SelectedItem);
        }

        protected void cboDateTimeOps_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Check the selected index
            switch (cboDateTimeOps.SelectedIndex)
            {
                case 0:
                    // Disable all
                    txtDateTimeOps.Enabled = false;
                    cmdAddDateTimeRange.Enabled = false;
                    break;
                case 3:
                case 4:
                case 9:
                case 10:
                    // Enable basic with range
                    txtDateTimeOps.Enabled = true;
                    cmdAddDateTimeRange.Enabled = true;
                    break;
                case 1:
                case 2:
                case 5:
                case 6:
                case 7:
                case 8:
                    // Enable basic only
                    txtDateTimeOps.Enabled = true;
                    cmdAddDateTimeRange.Enabled = false;
                    break;
            }
        }

        protected void cmdAddDateTimeRange_Click(object sender, EventArgs e)
        {
            DateTime dt;

            // If the value is date/time
            if (DateTime.TryParse(txtDateTimeOps.Text, out dt) == true)
            {
                // If we're not doing a BETWEEN, proceed. If we are, and the item count < 2, proceed
                if (((cboDateTimeOps.SelectedIndex < 9) || (cboDateTimeOps.SelectedIndex > 10)) || (lstDateTimeOps.Items.Count < 2))
                {
                    // Create a list item for the value
                    System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem("'" + txtDateTimeOps.Text + "'", "'" + txtDateTimeOps.Text + "'");
                    // Add the item
                    lstDateTimeOps.Items.Add(li);
                    // Reset the value
                    txtDateTimeOps.Text = "";
                }
            }
        }

        protected void cmdMoveRightDateTime_Click(object sender, EventArgs e)
        {
            // Default to "not okay"
            bool bOK = false;
            // Text and Value for the date/time filter item
            string sText = "";
            string sValue = "";

            // Check the operation being performed
            switch (cboDateTimeOps.SelectedIndex)
            {
                case 1:
                case 2:
                case 5:
                case 6:
                case 7:
                case 8:
                    DateTime dt;

                    // Check if the input is a date/time
                    if (DateTime.TryParse(txtDateTimeOps.Text, out dt) == true)
                    {
                        // "okay"
                        bOK = true;
                        // Build the clause
                        sValue = "(" + lstDateTime.SelectedItem.Value + " " + cboDateTimeOps.SelectedItem.Value + " '" + txtDateTimeOps.Text + "')";
                    }
                    break;
                case 3:
                case 4:
                    // "okay"
                    bOK = true;
                    // Loop through the range
                    for (int i = 0; i < lstDateTimeOps.Items.Count; i++)
                    {
                        // Append the item values
                        sValue += lstDateTimeOps.Items[i].Text + ", ";
                    }
                    // Chop off trailing comma
                    sValue = sValue.Substring(0, sValue.Length - 2);
                    // Build the full value
                    sValue = "(" + lstDateTime.SelectedItem.Value + " " + cboDateTimeOps.SelectedItem.Value + " (" + sValue + "))";
                    break;
                case 9:
                case 10:
                    // If we're doing a BETWEEN operation
                    if (lstDateTimeOps.Items.Count == 2)
                    {
                        // "okay"
                        bOK = true;
                        // Build the clause
                        sValue = lstDateTimeOps.Items[0].Value + " AND " + lstDateTimeOps.Items[1].Value;
                    }
                    // Build the full value
                    sValue = "(" + lstDateTime.SelectedItem.Value + " " + cboDateTimeOps.SelectedItem.Value + " " + sValue + ")";
                    break;
            }
            // If the value exceeds the defined column width
            if (sValue.Length > iColWidth)
            {
                // Truncate the display, append ellipsis
                sText = sValue.Substring(0, iColWidth) + "...";
            }
            else
            {
                // Otherwise, show the full value
                sText = sValue;
            }

            // If everything is "okay"
            if (bOK == true)
            {
                // Create the list item for the filter
                System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem(sText, sValue);
                // Add the item
                lstDateTimeFilters.Items.Add(li);

                ReportDefinition.DateTimeFilters.Add(sValue);
            }

            // Clear the input controls
            txtDateTimeOps.Text = "";
            lstDateTimeOps.Items.Clear();
        }

        protected void cmdMoveLeftDateTime_Click(object sender, EventArgs e)
        {
            ReportDefinition.DateTimeFilters.Remove(lstDateTimeFilters.SelectedValue);

            // Remove the filter item
            lstDateTimeFilters.Items.Remove(lstDateTimeFilters.SelectedItem);
        }

        protected void cboStringOps_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Check the selected index
            switch (cboStringOps.SelectedIndex)
            {
                case 0:
                    // Disable all
                    txtStringOps.Enabled = false;
                    cmdAddStringRange.Enabled = false;
                    break;
                case 3:
                case 4:
                    // Enable basic with range
                    txtStringOps.Enabled = true;
                    cmdAddStringRange.Enabled = true;
                    break;
                case 1:
                case 2:
                case 5:
                case 6:
                case 7:
                case 8:
                    // Enable basic only
                    txtStringOps.Enabled = true;
                    cmdAddStringRange.Enabled = false;
                    break;
            }
        }

        protected void cmdAddStringRange_Click(object sender, EventArgs e)
        {
            // Create a list item for the value
            System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem("'" + txtStringOps.Text + "'", "'" + txtStringOps.Text + "'");
            // Add the item
            lstStringOps.Items.Add(li);
            // Reset the value
            txtStringOps.Text = "";
        }

        protected void cmdMoveRightString_Click(object sender, EventArgs e)
        {
            // Default to "not okay"
            bool bOK = false;
            // Text and Value for the string filter item
            string sText = "";
            string sValue = "";

            // Check the operation being performed
            switch (cboStringOps.SelectedIndex)
            {
                case 1:
                case 2:
                case 5:
                case 6:
                case 7:
                case 8:
                    // "okay"
                    bOK = true;
                    // If we're not doing a LIKE clause
                    if (cboStringOps.SelectedItem.Value.IndexOf("_") == -1)
                    {
                        // Build the clause
                        sValue = "(" + lstString.SelectedItem.Value + " " + cboStringOps.SelectedItem.Value + " '" + txtStringOps.Text + "')";
                    }
                    else
                    {
                        // Build the LIKE clause
                        sValue = "(" + lstString.SelectedItem.Value + " " + cboStringOps.SelectedItem.Value.Replace("_", txtStringOps.Text) + ")";
                    }
                    break;
                case 3:
                case 4:
                    // "okay"
                    bOK = true;
                    // Loop through the range
                    for (int i = 0; i < lstStringOps.Items.Count; i++)
                    {
                        // Append the item values
                        sValue += lstStringOps.Items[i].Text + ", ";
                    }
                    // Chop off trailing comma
                    sValue = sValue.Substring(0, sValue.Length - 2);
                    // Build the full value
                    sValue = "(" + lstString.SelectedItem.Value + " " + cboStringOps.SelectedItem.Value + " (" + sValue + "))";
                    break;
            }
            // If the value exceeds the defined column width
            if (sValue.Length > iColWidth)
            {
                // Truncate the display, append ellipsis
                sText = sValue.Substring(0, iColWidth) + "...";
            }
            else
            {
                // Otherwise, show the full value
                sText = sValue;
            }

            // If everything is "okay"
            if (bOK == true)
            {
                // Create the list item for the filter
                System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem(sText, sValue);
                // Add the item
                lstStringFilters.Items.Add(li);

                ReportDefinition.StringFilters.Add(sValue);
            }

            // Clear the input controls
            txtStringOps.Text = "";
            lstStringOps.Items.Clear();
        }

        protected void cmdMoveLeftString_Click(object sender, EventArgs e)
        {
            ReportDefinition.StringFilters.Remove(lstStringFilters.SelectedValue);

            // Remove the filter item
            lstStringFilters.Items.Remove(lstStringFilters.SelectedItem);
        }

        protected void cmdMoveRightBoolean_Click(object sender, EventArgs e)
        {
            // Default to "not okay"
            bool bOK = false;
            // Text and Value for the boolean filter item
            string sValue = "";
            string sText = "";

            // Check the operation being performed
            switch (cboBooleanOps.SelectedItem.Value)
            {
                case "0":
                case "1":
                    // "okay"
                    bOK = true;
                    // Build the clause
                    sValue = "(" + lstBoolean.SelectedItem.Value + " = " + cboBooleanOps.SelectedItem.Value + ")";
                    break;
            }
            // If the value exceeds the defined column width
            if (sValue.Length > iColWidth)
            {
                // Truncate the display, append ellipsis
                sText = sValue.Substring(0, iColWidth) + "...";
            }
            else
            {
                // Otherwise, show the full value
                sText = sValue;
            }

            // If everything is "okay"
            if (bOK == true)
            {
                // Create the list item for the filter
                System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem(sText, sValue);
                // Add the item
                lstBooleanFilters.Items.Add(li);

                ReportDefinition.BooleanFilters.Add(sValue);
            }
        }

        protected void cmdMoveLeftBoolean_Click(object sender, EventArgs e)
        {
            ReportDefinition.BooleanFilters.Remove(lstBooleanFilters.SelectedValue);

            // Remove the filter item
            lstBooleanFilters.Items.Remove(lstBooleanFilters.SelectedItem);
        }

        protected void cmdCal_Click(object sender, ImageClickEventArgs e)
        {
            // If we can use date/time operations
            if (txtDateTimeOps.Enabled == true)
            {
                // Popup the calendar window
                this.ClientScript.RegisterClientScriptBlock(this.GetType(), "CalendarPopup", "<script>window.open('calendar.aspx?id=htmlReports6.txtDateTimeOps', 'calendar', 'location=0, menubar=0, resizable=1, scrollbars=0, toolbar=0, height=300, width=300');</script>");
            }
        }

        protected void lstNumeric_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Enable numeric ops
            cboNumericOps.Enabled = true;
            // Disable and reset the others
            cboDateTimeOps.Enabled = false;
            cboStringOps.Enabled = false;
            cboBooleanOps.Enabled = false;
            lstDateTime.SelectedIndex = -1;
            lstString.SelectedIndex = -1;
            lstBoolean.SelectedIndex = -1;
            txtNumericOps.Text = "";
            lstNumericOps.Items.Clear();
            txtDateTimeOps.Text = "";
            lstDateTimeOps.Items.Clear();
            txtStringOps.Text = "";
            lstStringOps.Items.Clear();
            cmdAddNumericRange.Enabled = false;
            cmdAddDateTimeRange.Enabled = false;
            cmdAddStringRange.Enabled = false;
            cboNumericOps.SelectedIndex = 0;
            cboDateTimeOps.SelectedIndex = 0;
            cboStringOps.SelectedIndex = 0;
            cboBooleanOps.SelectedIndex = 0;
        }

        protected void lstDateTime_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Enable date/time ops
            cboDateTimeOps.Enabled = true;
            // Disable and reset the others
            cboNumericOps.Enabled = false;
            cboStringOps.Enabled = false;
            cboBooleanOps.Enabled = false;
            lstNumeric.SelectedIndex = -1;
            lstString.SelectedIndex = -1;
            lstBoolean.SelectedIndex = -1;
            txtNumericOps.Text = "";
            lstNumericOps.Items.Clear();
            txtDateTimeOps.Text = "";
            lstDateTimeOps.Items.Clear();
            txtStringOps.Text = "";
            lstStringOps.Items.Clear();
            cmdAddNumericRange.Enabled = false;
            cmdAddDateTimeRange.Enabled = false;
            cmdAddStringRange.Enabled = false;
            cboNumericOps.SelectedIndex = 0;
            cboDateTimeOps.SelectedIndex = 0;
            cboStringOps.SelectedIndex = 0;
            cboBooleanOps.SelectedIndex = 0;
        }

        protected void lstString_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Enable string ops
            cboStringOps.Enabled = true;
            // Disable and reset the others
            cboNumericOps.Enabled = false;
            cboDateTimeOps.Enabled = false;
            cboBooleanOps.Enabled = false;
            lstNumeric.SelectedIndex = -1;
            lstDateTime.SelectedIndex = -1;
            lstBoolean.SelectedIndex = -1;
            txtNumericOps.Text = "";
            lstNumericOps.Items.Clear();
            txtDateTimeOps.Text = "";
            lstDateTimeOps.Items.Clear();
            txtStringOps.Text = "";
            lstStringOps.Items.Clear();
            cmdAddNumericRange.Enabled = false;
            cmdAddDateTimeRange.Enabled = false;
            cmdAddStringRange.Enabled = false;
            cboNumericOps.SelectedIndex = 0;
            cboDateTimeOps.SelectedIndex = 0;
            cboStringOps.SelectedIndex = 0;
            cboBooleanOps.SelectedIndex = 0;
        }

        protected void lstBoolean_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Enable boolean ops
            cboBooleanOps.Enabled = true;
            // Disable and reset the others
            cboNumericOps.Enabled = false;
            cboDateTimeOps.Enabled = false;
            cboStringOps.Enabled = false;
            lstNumeric.SelectedIndex = -1;
            lstDateTime.SelectedIndex = -1;
            lstString.SelectedIndex = -1;
            txtNumericOps.Text = "";
            lstNumericOps.Items.Clear();
            txtDateTimeOps.Text = "";
            lstDateTimeOps.Items.Clear();
            txtStringOps.Text = "";
            lstStringOps.Items.Clear();
            cmdAddNumericRange.Enabled = false;
            cmdAddDateTimeRange.Enabled = false;
            cmdAddStringRange.Enabled = false;
            cboNumericOps.SelectedIndex = 0;
            cboDateTimeOps.SelectedIndex = 0;
            cboStringOps.SelectedIndex = 0;
            cboBooleanOps.SelectedIndex = 0;
        }

        protected void cmdTest_Click(object sender, EventArgs e)
        {
            // Create a connection object
            using (System.Data.OleDb.OleDbConnection oleConn = new System.Data.OleDb.OleDbConnection(ReportDefinition.ConnectionString))
            {
                // Get the row count
                using (System.Data.OleDb.OleDbCommand oleComm = new System.Data.OleDb.OleDbCommand("SELECT COUNT(*) FROM \"" + ReportDefinition.View + "\"" + BuildWhere(), oleConn))
                {
                    oleComm.Connection.Open();
                    lblQueryRowCount.Text = oleComm.ExecuteScalar().ToString();
                    oleComm.Connection.Close();
                }
            }
        }

        /// <summary>
        /// Build the SQL WHERE clause for the current filters
        /// </summary>
        /// <returns>Returns a SQL-92 compliant WHERE clause, starting with "WHERE", unless there are no filters in use, whereupon a zero-length string is returned.</returns>
        private string BuildWhere()
        {
            // Defualt to a zero length string
            string sRet = "";

            // Join the numeric filters
            sRet += String.Join(" AND ", ReportDefinition.NumericFilters.ToArray());
            // If the numeric filter does not trail with " AND "
            if ((sRet.Length > 0) && (sRet.LastIndexOf(" AND ") != (sRet.Length - 5)))
            {
                // Tack it on
                sRet += " AND ";
            }

            // Join the date/time filters
            sRet += String.Join(" AND ", ReportDefinition.DateTimeFilters.ToArray());
            // If the date/time filter does not trail with " AND "
            if ((sRet.Length > 0) && (sRet.LastIndexOf(" AND ") != (sRet.Length - 5)))
            {
                // Tack it on
                sRet += " AND ";
            }

            // Join the string filters
            sRet += String.Join(" AND ", ReportDefinition.StringFilters.ToArray());
            // If the string filter does not trail with " AND "
            if ((sRet.Length > 0) && (sRet.LastIndexOf(" AND ") != (sRet.Length - 5)))
            {
                // Tack it on
                sRet += " AND ";
            }

            // Join the boolean filters
            sRet += String.Join(" AND ", ReportDefinition.BooleanFilters.ToArray());
            // If the filter trails with " AND "
            if (sRet.LastIndexOf(" AND ") == (sRet.Length - 5))
            {
                // Chop it off
                sRet = sRet.Substring(0, sRet.Length - 5);
            }

            // If the a SQL clause exists
            if (sRet.Length > 0)
            {
                // Prepend it with " WHERE "
                sRet = " WHERE " + sRet;
            }

            // Return the string
            return sRet;
        }
    }
}